<template>
    <div class="audit app-container">
      <div class="menu el-col-14">
        <el-button type="default" v-if="showMe?true:false" @click="allSQLs">全部</el-button>
        <el-button type="default" v-if="showMe?false:true" @click="meSQLs">与我相关</el-button>
        <el-date-picker v-show="showDate"
          v-model="dateValue"
          type="datetimerange"
          range-separator="-"
          value-format="yyyy-MM-dd HH:mm:ss"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="['09:00:00', '18:00:00']"
          @change="changeDate">
        </el-date-picker>
        <el-button type="default" v-if="showDate?false:true" @click="showDate=!showDate">过滤时间</el-button>
        <el-button type="default" v-if="showDate?true:false" @click="showDate=!showDate">取消</el-button>
      </div>
      <div class="search el-col-10">
        <el-input placeholder="搜索关键字: ID、环境、提交人、审核人，任一 " v-model="params.search" @keyup.enter.native="search" class="input-with-select">
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
        </el-input>
      </div>

      <el-table :data="dataList" v-loading="isLoading"  element-loading-text="拼命加载中" border style="width: 100%">

        <el-table-column type="expand">
          <template slot-scope="props">
            <el-form label-position="left" inline class="demo-table-expand" label-width="90px">
              <el-form-item label="审核组">
                <span>{{ props.row.group }}</span>
              </el-form-item>
              <el-form-item label="操作备注">
                <span>{{ props.row.remark?props.row.remark:'-' }}</span>
              </el-form-item>
              <el-form-item label="执行错误">
                <span>{{ props.row.execute_errors?props.row.execute_errors: '-'  }}</span>
              </el-form-item>
              <el-form-item label="执行影响">
                <span>{{ props.row.exe_affected_rows?props.row.exe_affected_rows: '-' }} row</span>
              </el-form-item>
              <el-form-item label="回滚库">
                <span>{{ props.row.rollback_db?props.row.rollback_db: '-' }}</span>
              </el-form-item>
              <el-form-item label="回滚编号">
                <span>{{ props.row.rollback_opid?props.row.rollback_opid: '-' }}</span>
              </el-form-item>
              <el-form-item label="创建时间">
                <span>{{ props.row.ctime }}</span>
              </el-form-item>
              <el-form-item label="更新时间">
                <span>{{ props.row.utime }}</span>
              </el-form-item>
            </el-form>
          </template>
        </el-table-column>

        <el-table-column sortable align="center" min-width="100" prop="id" label="ID"></el-table-column>
        <el-table-column sortable align="center" min-width="100" prop="commiter" label="提交人"></el-table-column>
        <el-table-column sortable align="center" min-width="100" prop="treater" label="审核人"></el-table-column>
        <el-table-column sortable align="center" min-width="110" prop="database" label="数据库"></el-table-column>
        <!-- 环境标签，利用固定值envs列表循环 -->
        <el-table-column sortable align="center" min-width="120" prop="env" label="执行环境"
                         :filters="envs" :filter-method="filterTag" filter-placement="bottom-end">
          <template slot-scope="scope" >
            <span v-for="env in envs">
              <span v-show="scope.row.env===env.value">
                <el-tag :type="env.color"
                        disable-transitions>{{ env.text }}</el-tag>
                </span>
            </span>
          </template>
        </el-table-column>
        <el-table-column sortable align="center" min-width="100" prop="status" label="状态"
                         :filters="status" :filter-method="filterStatus" filter-placement="bottom-end">
          <template slot-scope="scope" >
            <span v-for="s in status">
              <span v-show="scope.row.status===s.value">
                <el-tag :type="s.color"
                        disable-transitions>{{ s.text }}</el-tag>
                </span>
            </span>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="sql_content" label="SQL">
          <template slot-scope="scope">
            <el-button size="small" type="text" @click="viewSQL(scope.row)">查看</el-button>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="remark" label="备注">
          <template slot-scope="scope">
            <el-tooltip class="item" effect="dark" :content="scope.row.remark" placement="top-start">
              <el-button size="small" type="text">查看</el-button>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column sortable align="center" width="160" prop="utime" label="更新时间"></el-table-column>
        <el-table-column fixed="right" align="center" label="操作" width="120">
          <template slot-scope="scope">
            <el-button v-if="scope.row.status===0" size="small" type="text"
                       @click="action(scope.row.id, 'rollback')">回滚</el-button>
            <el-button v-else size="small" type="text"
                       :disabled="scope.row.status===-1?false:true"
                       @click="action(scope.row.id, 'execute')">执行</el-button>
            <el-button size="small" type="text" @click="action(scope.row.id, 'reject')"
                       :disabled="scope.row.status===-1?false:true">放弃</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pageination" v-show="total>2">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          @current-change="handleCurrentChange"
          @size-change="handleSizeChange"
          :page-sizes="[5, 10, 15, 20]"
          :current-page.sync="params.page"
          :page-size="params.page_size"
          :total="total">
        </el-pagination>
      </div>

      <el-dialog title="SQL语句" :visible.sync="SQLDialogVisible">
        <div class="code-container">
          <pre><code v-text="currentSQL"></code></pre>
        </div>
      </el-dialog>

    </div>
</template>

<script>
  import { mapGetters } from 'vuex'
  import { getSQLList, auditSQLAction } from '@/api/sqlaudit'
  import hljs from 'highlight.js'
  // import 'highlight.js/styles/xcode.css'
  import 'highlight.js/styles/atom-one-light.css'

  const highlight = () => { // SQL语法高亮
    const preEl = document.querySelectorAll('pre code')

    preEl.forEach((el) => {
      hljs.highlightBlock(el)
    })
  }

  export default {
    name: 'audit',
    computed: {
      ...mapGetters({
        envs: 'envs',
        userid: 'userid'
      })
    },
    mounted() {
      highlight()
    },
    updated() {
      highlight()
    },
    data() {
      return {
        showDate: false,
        showMe: false,
        isLoading: false,
        SQLDialogVisible: false,
        popoverVisible: false,
        dataList: [],
        total: 0,
        params: {
          page: 1,
          page_size: 10,
          search: '',
          daterange: ''
        },
        currentSQL: '',
        status: [
          { value: -3, text: '已回滚', color: 'info' },
          { value: -2, text: '已暂停', color: 'default' },
          { value: -1, text: '待执行', color: 'primary' },
          { value: 0, text: '已执行', color: 'success' },
          { value: 1, text: '已放弃', color: 'warning' },
          { value: 2, text: '已失败', color: 'danger' }
        ],
        dateValue: ''
      }
    },
    created() {
      this.fetchData(this.params)
    },
    methods: {
      meSQLs() {
        this.showMe = true
        this.fetchData({ page_size: 10, page: 1, user: this.userid })
      },
      allSQLs() {
        this.showMe = false
        this.fetchData({ page_size: 10, page: 1 })
      },
      search() {
        this.fetchData(this.params)
      },
      // 改变页码和页面大小时获取对应的数据
      handleCurrentChange(val) {
        this.params.page = val
        this.fetchData(this.params)
      },
      handleSizeChange(val) {
        this.params.page_size = val
        this.fetchData(this.params)
      },
      filterTag(value, row) {
        // return this.fetchData({ env: value })
        return row.env === value
      },
      filterStatus(value, row) {
        // this.fetchData({ status: value })
        return row.status === value
      },
      changeDate() {
        if (this.dateValue) {
          this.params.daterange = `${this.dateValue[0]},${this.dateValue[1]}`
          this.fetchData(this.params)
        }
      },
      fetchData(params) {
        this.isLoading = true
        getSQLList(params).then(
          res => {
            this.dataList = res.results
            this.total = res.count
          }).catch(
          () => {
            this.$message.error('获取数据失败')
          })
        this.isLoading = false
      },
      viewSQL(row) {
        this.currentSQL = row.sql_content
        this.SQLDialogVisible = true
      },
      action(id, action) {
        let m = ''
        if (action === 'execute') {
          m = '执行'
        } else if (action === 'rollback') {
          m = '回滚'
        } else {
          m = '放弃'
        }
        this.$confirm(`确认 ${m} 此SQL?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(
          () => {
            auditSQLAction(id, action).then(
              res => {
                const status = res.status
                const data = res.data
                const msg = res.msg
                if (status === 0) {
                  const time = data.execute_time ? `<p>耗时: ${data.execute_time} sec.</p>` : ''
                  const rows = data.affected_rows ? `<p>影响: ${data.affected_rows} row.</p>` : ''
                  const info = data.info ? `<p>信息: ${data.info}</p>` : ''
                  const msg_body = msg ? `<p>${msg}</p>` : ''
                  this.$notify({ title: `${m}成功`, dangerouslyUseHTMLString: true,
                    message: `${time}${rows}${msg_body}${info}`,
                    type: 'success', duration: 8000, offset: 32 })
                } else {
                  const msg = res.msg
                  this.$notify({ title: `${m}出错`, message: msg, type: 'error', duration: 15000, offset: 32 })
                }
                this.fetchData(this.params)
              }).catch(
              () => {
                this.$message.error('动作发生错误，更新SQL状态')
                this.fetchData(this.params)
              })
          }).catch(
          () => {
            this.$message.info('已取消操作')
          })
      }
    }
  }
</script>

<style lang="scss" scoped>
.audit {
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 50%;
  }

  .pageination {
    text-align: center;
    margin-top: 15px;
  }
  .search {
    margin-bottom: 10px;
  }
  .btn-wrapper {
    text-align: right;
  }
  .select {
    width: 100%;
  }
  .code-container {
    /*border: 1px solid #999999;*/
    /*border-radius: 3px;*/
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);

    pre {
      margin: 0;
      padding: 0;
    }
    code {
      margin: 0;
      padding: 8px;
      font-family: Consolas;
    }
  }
}
</style>
